from django.views.generic.base import View
from django.shortcuts import render
from django.db.models import Q
from django.http import JsonResponse
from django.conf import settings
from pure_pagination import Paginator, PageNotAnInteger
from utils.mixin_utils import LoginRequiredMixin
from utils.form_utils import get_form_errors
from systems.models import Dictionary
from systems.forms import DictionaryForm
from systems.views.dept import get_dept_tree2


class ListView(LoginRequiredMixin, View):
    def get(self, request):
        v_search = request.GET.get('search')
        if v_search:
            v_search = v_search.strip()
            v_objs = Dictionary.objects.filter(Q(code__icontains=v_search) | Q(label__icontains=v_search) |
                                               Q(value__icontains=v_search) | Q(remark__icontains=v_search),
                                               is_delete=0).order_by('parent_id', 'sort')
        else:
            v_objs = Dictionary.objects.filter(is_delete=0).order_by('parent_id', 'sort')

        # 分页功能实现
        try:
            page = request.GET.get('page', 1)
        except PageNotAnInteger:
            page = 1
        p = Paginator(v_objs, per_page=settings.PAGE_NUM, request=request)
        p_objs = p.page(page)
        p_start = (int(page) - 1) * settings.PAGE_NUM  # 避免分页后每行数据序号从1开始
        return render(request, 'systems/dictionary_list.html',
                      {'p_objs': p_objs, 'p_start': p_start, 'p_sum': v_objs.count,
                       'h_search': v_search})


class AddView(LoginRequiredMixin, View):
    def get(self, request):
        return render(request, 'systems/dictionary.html', {'h_dictionarys': get_dictionary_tree2(),
                                                           'h_dept_belongs': get_dept_tree2()})

    def post(self, request):
        v_form = DictionaryForm(request.POST)
        if v_form.is_valid():
            new_obj = v_form.save(commit=False)
            new_obj.creator = request.user.username
            new_obj.modifier = request.user.username
            # 数据归属部门不填，则默认为当前创建用户的部门ID
            if new_obj.dept_belong_id is None:
                new_obj.dept_belong_id = request.user.dept_id
            new_obj.save()
            return JsonResponse({'code': '200', 'msg': '新增成功'})
        else:
            return JsonResponse({'code': '444', 'msg': get_form_errors(v_form)})


class DetailView(LoginRequiredMixin, View):
    def get(self, request):
        v_obj = Dictionary.objects.get(id=request.GET.get('id'))
        return render(request, 'systems/dictionary.html', {'h_obj': v_obj,
                                                           'h_dictionarys': get_dictionary_tree2(v_obj.parent),
                                                           'h_dept_belongs': get_dept_tree2(v_obj.dept_belong_id)})


class ModifyView(LoginRequiredMixin, View):
    def post(self, request):
        v_obj = Dictionary.objects.get(id=request.POST.get('id'))
        v_form = DictionaryForm(request.POST, instance=v_obj)
        if v_form.is_valid():
            old_obj = v_form.save(commit=False)
            old_obj.modifier = request.user.username
            # 数据归属部门不填，则默认为当前创建用户的部门ID
            if old_obj.dept_belong_id is None:
                old_obj.dept_belong_id = request.user.dept_id
            old_obj.save()
            return JsonResponse({'code': '200', 'msg': '修改成功'})
        else:
            return JsonResponse({'code': '444', 'msg': get_form_errors(v_form)})


class DeleteView(LoginRequiredMixin, View):
    def get(self, request, i_id):
        v_user = Dictionary.objects.get(id=i_id)
        v_user.delete()
        return JsonResponse({'code': '200', 'msg': '删除成功'})


def get_dictionary_tree(i_dic=None):
    """
    获取字典树，只能选子节点
    YPN 2021-09-19 Create
    :return: 返回树形的字典结构HTML
    """
    dic_tree = ''
    dics = Dictionary.objects.filter(is_delete=0, status=1)

    def get_blank(i_num):
        i = 1
        result = ''
        while i <= i_num:
            result += '&nbsp;&nbsp;'
            i = i + 1
        return result

    def get_child(i_parent_dic, i_blank_num, i_selected_dic):
        """递归获取树的子节点"""
        exist_child = False
        child_tree = ''
        for dic1 in dics:
            if dic1.parent is not None and dic1.parent == i_parent_dic:
                exist_child = True
                child_tree += get_child(dic1, i_blank_num + 1, i_selected_dic)

        if exist_child:
            return f'<optgroup label="{get_blank(i_blank_num + 1)}{i_parent_dic.label}">{child_tree}</optgroup>'
        else:
            is_selected = False
            if i_selected_dic is not None:
                for mbtn in i_selected_dic:
                    if mbtn.key == i_parent_dic.value:
                        is_selected = True
                        break
            if is_selected:
                return f'<option selected value="{i_parent_dic.label}|{i_parent_dic.value}">{get_blank(i_blank_num + 1)}{i_parent_dic.label} | {i_parent_dic.value}</option>'
            else:
                return f'<option value="{i_parent_dic.label}|{i_parent_dic.value}">{get_blank(i_blank_num + 1)}{i_parent_dic.label} | {i_parent_dic.value}</option>'

    for dic in dics:
        if dic.parent is None:
            if i_dic is None:
                dic_tree = get_child(dic, -1, None)
            else:
                dic_tree = get_child(dic, -1, i_dic)

    return dic_tree


def get_dictionary_tree2(i_dic=None):
    """
    获取字典树，可选父节点
    YPN 2021-09-19 Create
    :return: 返回树形的字典结构HTML
    """
    dic_tree = ''
    dics = Dictionary.objects.filter(is_delete=0, status=1)

    def get_blank(i_num):
        i = 1
        result = ''
        while i <= i_num:
            result += '&nbsp;&nbsp;'
            i = i + 1
        return result

    def get_child(i_dic_id, i_dic_label, i_blank_num, i_selected_dic_id):
        """递归获取树的子节点"""
        exist_child = False
        child_tree = ''
        for dic1 in dics:
            if dic1.parent is not None and dic1.parent.id == i_dic_id:
                exist_child = True
                child_tree += get_child(dic1.id, dic1.label, i_blank_num + 1, i_selected_dic_id)

        if exist_child:
            if i_dic_id == i_selected_dic_id:
                return f'<option selected value="{i_dic_id}">{get_blank(i_blank_num + 1)}{i_dic_label}</option>{child_tree}'
            else:
                return f'<option value="{i_dic_id}">{get_blank(i_blank_num + 1)}{i_dic_label}</option>{child_tree}'
        else:
            if i_dic_id == i_selected_dic_id:
                return f'<option selected value="{i_dic_id}">{get_blank(i_blank_num + 1)}{i_dic_label}</option>'
            else:
                return f'<option value="{i_dic_id}">{get_blank(i_blank_num + 1)}{i_dic_label}</option>'

    for dic in dics:
        if dic.parent is None:
            if i_dic is None:
                dic_tree = get_child(dic.id, dic.label, -1, 0)
            else:
                dic_tree = get_child(dic.id, dic.label, -1, i_dic.id)

    return dic_tree
